using System;
using System.Collections.Generic;
using Godot;

public class GameUtil
{
    public static Texture2D GetCacheTexture(Dictionary<int, Texture2D> dic, int id, string path)
    {
        if (dic.ContainsKey(id))
        {
            return dic[id];
        }
        else
        {
            dic.Add(id, ResourceLoader.Load<Texture2D>(path));
            return dic[id];
        }
    }

    public static Texture2D GetRobotPortrait(int id)
    {
        return GetCacheTexture(Global.RobotPortrailDic, id, $"{Path.PORTRAIT_ROOT}{id}.png");
    }
    public static Texture2D GetRobotIcon(int id, bool isPlayer, bool isAlly)
    {
        var mid = isPlayer || isAlly ? "blue" : "red";
        return GetCacheTexture(Global.RobotIconDic, id, $"{Path.ICON_ROOT}{mid}/{id}.png");
    }
    public static Texture2D GetPilotAvatar(int id)
    {
        return GetCacheTexture(Global.PilotAvatarDic, id, $"{Path.AVATAR_ROOT}{id}.png");
    }

    public static AudioStream GetAudioStream(string path)
    {
        if (Global.AudioStreamDic.ContainsKey(path))
        {
            return Global.AudioStreamDic[path];
        }
        else
        {
            Global.AudioStreamDic.Add(path, ResourceLoader.Load<AudioStream>($"{Path.AUDIO_ROOT}/{Global.AudioPathDic[path]}"));
            return Global.AudioStreamDic[path];
        }
    }


    public static PackedScene GetWeaponAnimate(string path)
    {
        if (Global.WeaponAnimateDic.ContainsKey(path))
        {
            return Global.WeaponAnimateDic[path];
        }
        else
        {
            Global.WeaponAnimateDic.Add(path, ResourceLoader.Load<PackedScene>($"{Path.WEAPON_ROOT}{path}.tscn"));
            return Global.WeaponAnimateDic[path];
        }
    }

    public static void LoadAllJsonData()
    {
        LoadBuffJsonData();
        LoadSkillJsonData();
        LoadWeponJsonData();
        LoadPilotJsonData();
        LoadRobotJsonData();
        LoadAudioJsonData();
    }

    private static void LoadBuffJsonData()
    {
        var json = FileUtil.ReadString($"{Path.TEMPLATE_ROOT}/buff_template.json");
        var buff = JSONUtil.ParseList<BuffModel>(json);
        foreach (var item in buff)
        {
            Global.BuffModelDic.Add(item.TemplateID, item);
        }

    }


    private static void LoadAudioJsonData()
    {
        var json = FileUtil.ReadString($"{Path.JSON_ROOT}/audio/audios.json");
        var list = JSONUtil.Parse<Dictionary<string, string>>(json);
        foreach (var item in list)
        {
            Global.AudioPathDic.Add(item.Key, item.Value);
        }
    }


    private static void LoadRobotJsonData()
    {
        var json = FileUtil.ReadString($"{Path.TEMPLATE_ROOT}/robot_template.json");
        var list = JSONUtil.ParseList<RobotModel>(json);
        foreach (var item in list)
        {
            Global.RobotModelDic.Add(item.TemplateID, item);
        }
    }

    private static void LoadPilotJsonData()
    {
        var json = FileUtil.ReadString($"{Path.TEMPLATE_ROOT}/pilot_template.json");
        var list = JSONUtil.ParseList<PilotModel>(json);
        foreach (var item in list)
        {
            Global.PilotModelDic.Add(item.TemplateID, item);
        }
    }

    private static void LoadWeponJsonData()
    {
        var json = FileUtil.ReadString($"{Path.TEMPLATE_ROOT}/weapon_template.json");
        var list = JSONUtil.ParseList<SkillModel>(json);
        foreach (var item in list)
        {
            Global.WeaponModelDic.Add(item.SkillID, item);
        }
    }

    private static void LoadSkillJsonData()
    {
        var json = FileUtil.ReadString($"{Path.TEMPLATE_ROOT}/skill_template.json");
        var list = JSONUtil.ParseList<SkillModel>(json);
        foreach (var item in list)
        {
            Global.SkillModelDic.Add(item.TemplateID, item);
        }
    }


    public static string TransRobotType(RobotMoveType type)
    {
        return type switch
        {
            RobotMoveType.AIR => "空",
            RobotMoveType.LAND => "地",
            RobotMoveType.OCEAN => "海",
            _ => "无",
        };
    }

    public static void FastAssignment(object source, object target)
    {
        var t = source.GetType();
        var f = t.GetFields();
        foreach (var item in f)
        {
            item.SetValue(target, item.GetValue(source));
        }
        var p = t.GetProperties();
        foreach (var item in p)
        {
            if (item.SetMethod != null)
                item.SetValue(target, item.GetValue(source));
        }
    }

    /// <summary>
    /// 抄来的成长计算公式
    /// </summary>
    /// <param name="type"></param>
    /// <param name="level"></param>
    /// <returns></returns>
    public static int CalcLevelPlus(int type, int level)
    {
        /*  
        type 为
        0 +1.5向上取整
		1 +2
		2 +5
		3 +10
		4 麦塔斯速度专用 公式未知
		5 貌似未使用
		6 导弹专属 未知
		7 +2.5向下取整
		8 +3*/
        return type switch
        {
            0 => Mathf.CeilToInt(1.5f * level),
            1 => 2 * level,
            2 => 5 * level,
            3 => 10 * level,
            4 => Mathf.CeilToInt(Mathf.Pow(level, 1.5f)),
            5 => 0,
            6 => 0,
            7 => Mathf.FloorToInt(2.5f * level) - 1,
            8 => 3 * level,
            _ => Mathf.FloorToInt(1.5f * level),
        };
    }

    public static int Random(int min, int max)
    {
        var gen = new RandomNumberGenerator();
        return gen.RandiRange(min, max);
    }
    public static float Random(float min, float max)
    {
        var gen = new RandomNumberGenerator();
        return gen.RandfRange(min, max);
    }
    public static int RandomPercent()
    {
        return Random(0, 100);
    }

    public static bool IsChildNodeOf(Node node, Node child)
    {
        if (node == null) return false;
        if (child == null) return false;
        foreach (Node childNode in node.GetChildren())
        {
            if (childNode == child)
            {
                return true;
            }
        }
        return false;
    }

    public static Texture2D GetBuffIcon(string id)
    {
        if (Global.BuffIconDic.ContainsKey(id))
        {
            return Global.BuffIconDic[id];
        }
        else
        {
            Global.BuffIconDic.Add(id, ResourceLoader.Load<Texture2D>($"{Path.BUFF_ICON_ROOT}{id}.png"));
            return Global.BuffIconDic[id];
        }

    }
}